package com.ruoyi.common.config;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.List;

/**
 * @title: AbstractHttpClientConfig
 * @copyright: copyright (c) 2023
 * @author: jiangguanjun
 * @date: 2023/2/7 14:42
 * @firstReview:
 * @lastReview:
 * @desc:
 */
public class AbstractHttpClientConfig {
    /**
     * 说明：
     * 构建一个基于连接池的apache http client;
     */
    public CloseableHttpClient buildHttpClient(HttpPoolProperties httpPoolProperties) {

        // 1.
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();

        // 2. http池properties:
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(httpPoolProperties.getMaxTotal());
        connectionManager.setDefaultMaxPerRoute(httpPoolProperties.getDefaultMaxPerRoute());
        connectionManager.setValidateAfterInactivity(httpPoolProperties.getValidateAfterInactivity());

        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(httpPoolProperties.getSocketTimeout())
                .setConnectTimeout(httpPoolProperties.getConnectTimeout())
                .setConnectionRequestTimeout(httpPoolProperties.getConnectionRequestTimeout())
                .build();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .build();
    }


    /**
     * 说明:
     * 构建RestTemplate，并设置默认的字符集；
     */
    public RestTemplate buildRestTemplate(ClientHttpRequestFactory clientHttpRequestFactory, Charset charset) {
        // 1. + httpClient pool:
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);

        // 2. msg handler:
        this.messageConverterHandler(restTemplate, charset);

        return restTemplate;
    }

    /**
     * 重新设置StringHttpMessageConverter字符集为UTF-8，解决中文乱码问题
     */
    public void messageConverterHandler(RestTemplate restTemplate, Charset charset) {
        // 1. 消息转化器，字符集处理:
        List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();

        // 2. 重置:
        HttpMessageConverter<?> converterTarget = null;
        for (HttpMessageConverter<?> item : converterList) {
            if (StringHttpMessageConverter.class == item.getClass()) {
                converterTarget = item;
                break;
            }
        }
        if (null != converterTarget) {
            converterList.remove(converterTarget);
        }
        converterList.add(1, new StringHttpMessageConverter(charset));
    }

}
